﻿using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;

namespace RaptorEngine.Debugs
{
    public class DebugCamera : Camera
    {
        private float _rotationSpeed = .04f;
        public float RotationSpeed { get { return _rotationSpeed; } set { _rotationSpeed = value; } }
        private float _moveSpeed = .1f;
        public float MoveSpeed { get { return _moveSpeed; } set { _moveSpeed = value; } }
        private float _speedMultiplier = 1;
        public float SpeedMultiplier { get { return _speedMultiplier; } set { _speedMultiplier = value; } }

        float _leftrightRot;
        float _updownRot;

        private Vector3 _cameraPosition;

        public DebugCamera(Vector3 position, float updownRot, float leftrightRot)
            : base(Vector3.Forward, position)
        {
            this._leftrightRot = leftrightRot;
            this._updownRot = updownRot;
            _cameraPosition = position;
        }

        public void ProcessInput(float elapsedTime)
        {
                float xDifference = 0, yDifference = 0;

                if(GameEngine.Instance.Input.IsDown(Keys.Left))
                    xDifference -= _rotationSpeed;
                else if (GameEngine.Instance.Input.IsDown(Keys.Right))
                    xDifference += _rotationSpeed;

                if (GameEngine.Instance.Input.IsDown(Keys.Up))
                    yDifference -= _rotationSpeed;
                else if (GameEngine.Instance.Input.IsDown(Keys.Down))
                    yDifference += _rotationSpeed;

                _leftrightRot -= _rotationSpeed * xDifference * elapsedTime;
                _updownRot -= _rotationSpeed * yDifference * elapsedTime;

                Vector3 moveVector = new Vector3(0, 0, 0);

                if (GameEngine.Instance.Input.IsDown(Keys.LeftShift))
                    _speedMultiplier = 4;
                else
                    _speedMultiplier = 1;

                if (GameEngine.Instance.Input.IsDown(Keys.W))
                    moveVector += new Vector3(0, 0, -_speedMultiplier);
                if (GameEngine.Instance.Input.IsDown(Keys.S))
                    moveVector += new Vector3(0, 0, _speedMultiplier);
                if (GameEngine.Instance.Input.IsDown(Keys.D))
                    moveVector += new Vector3(_speedMultiplier, 0, 0);
                if (GameEngine.Instance.Input.IsDown(Keys.A))
                    moveVector += new Vector3(-_speedMultiplier, 0, 0);
                if (GameEngine.Instance.Input.IsDown(Keys.Space))
                    moveVector += new Vector3(0, _speedMultiplier, 0);
                if (GameEngine.Instance.Input.IsDown(Keys.LeftControl))
                    moveVector += new Vector3(0, -_speedMultiplier, 0);

                AddToCameraPosition(moveVector * elapsedTime * .2f);
        }

        private void AddToCameraPosition(Vector3 vectorToAdd)
        {
            Matrix moveRot = Matrix.CreateRotationX(_updownRot) * Matrix.CreateRotationY(_leftrightRot);
            Vector3 rotatedVector = Vector3.Transform(vectorToAdd, moveRot);
            _cameraPosition += _moveSpeed * rotatedVector;
        
            Matrix cameraRotation = Matrix.CreateRotationX(_updownRot) * Matrix.CreateRotationY(_leftrightRot);

            Vector3 cameraOriginalTarget = new Vector3(0, 0, -1);
            Vector3 cameraRotatedTarget = Vector3.Transform(cameraOriginalTarget, cameraRotation);
            Vector3 cameraTarget = _cameraPosition + cameraRotatedTarget;

            Vector3 cameraOriginalUpVector = new Vector3(0, 1, 0);
            Vector3 cameraRotatedUpVector = Vector3.Transform(cameraOriginalUpVector, cameraRotation);

            View = Matrix.CreateLookAt(_cameraPosition, cameraTarget, cameraRotatedUpVector);  
        }
    }
}
